<template>
  <el-container class="container_cover">
    <el-container class="container_center">
      <!-- 左侧导航菜单 -->
      <el-aside :width="asideWidth"> <Aside /> </el-aside>

      <!-- 右侧主体 -->
      <el-container class="container_right">
        <!-- 展开收缩图标 -->
        <el-icon size="20" color="#414346" @click="onFlod" class="icon_style">
          <component :is="collapse ? ArrowRight : ArrowLeft"></component>
        </el-icon>
        <!-- chat主体部分 -->
        <el-container class="chatview" ref="chatMessages">
          <!-- GPT 的回复 -->
          <div
            v-for="(message, index) in data.messages"
            :key="index"
            :class="{
              'gpt-message': message.type === accountType.GPT,
              'user-message': message.type === accountType.USER,
            }"
          >
            <div v-if="message.type === accountType.GPT">
              <div class="gpt_head">
                <el-avatar :src="message.avatar" :size="36"></el-avatar>
                <!-- <span style="margin-left: 10px">GPT</span> -->
              </div>

              <div
                class="message-text"
                :class="{ 'code-message': message.isCode }"
              >
                {{ message.text }}
              </div>
            </div>
            <template v-else>
              <!-- <div class="user_head">
                <span style="margin-right: 10px"> User </span>
                <el-avatar :src="message.avatar" size="default"></el-avatar>
              </div> -->

              <div class="message-text">{{ message.text }}</div>
            </template>
          </div>
          <div ref="lastMessage"></div>
        </el-container>
        <!-- footer -->
        <div class="sengChat">
          <!-- <el-popconfirm
            width="200"
            confirm-button-text="是"
            cancel-button-text="否"
            title="确认清空对话内容吗 ?"
            @confirm="confirmEvent"
          >
            <template #reference>
              <el-icon size="20" class="delete_icon"><Delete /></el-icon>
            </template>
          </el-popconfirm> -->
          <span class="kb-label">知识库</span>
          <el-select class="kb-select" v-model="selectedKnowledgeBase" placeholder="请选择知识库">
            <el-option
              v-for="kb in knowledgeBases"
              :key="kb.id"
              :label="kb.kb_name"
              :value="kb.id"
            />
          </el-select>
          <el-input
            v-model="chatValue.question"
            autocomplete="off"
            placeholder="想问我什么呢 ？"
            @keyup.enter="debouncedConfirmEvent"
          />
          <el-button
            v-if="!stopStatus"
            type="warning"
            @click="cancelRequest"
            :disabled="stopStatus"
          >
            终止
          </el-button>
          <el-button
            :disabled="chatStatus.btnDisabled"
            type="success"
            @click="debouncedConfirmEvent"
            :loading="chatStatus.loading"
          >
            <el-icon size="25" color="#fff"><Promotion /></el-icon>
          </el-button>
        </div>
      </el-container>
    </el-container>
  </el-container>
</template>
<script setup lang="ts">
import { IStore } from "@/App.vue";
import { QueryApi, KnowledgeApi } from "@/api/api";
import { accountType } from "@/config/Enum";
import Var from "@/config/Var";
import { useDebounce } from "@/hooks/UseDebounce";
import Aside from "@/views/home/Aside.vue";
import {
  ArrowLeft,
  ArrowRight,
  Delete,
  Expand,
  Promotion,
} from "@element-plus/icons-vue";
import { ElMessage, ElLoading } from "element-plus";
import { inject, nextTick, onMounted, reactive, ref, toRefs, watch } from "vue";
import chaticon from "../../../public/images/ChatGPT.svg";
import { fetchEventSource } from "@microsoft/fetch-event-source";

interface messageType {
  isCode: boolean; //是否代码
  isPreview: boolean; //是否gpt回复前的测试
  text: string;
  type: accountType;
  avatar?: string;
}

// 引入全局信息
const store = inject<IStore>("store");
// 引入防抖函数
const { debounce } = useDebounce();

const lastMessage = ref();
const knowledgeBases = ref([]);
const selectedKnowledgeBase = ref(null); // 存储选中的知识库 ID
const data = reactive<{
  // 左侧输入框收缩控制
  collapse: boolean;
  // 左侧输入框宽
  asideWidth: string;
  // 输入的内容
  chatValue: {
    question: string;
  };
  chatStatus: {
    // 发送按钮状态
    btnDisabled: boolean;
    // 请求状态
    loading: boolean;
  };
  // 对话信息
  messages: messageType[];
  // 手机端左侧抽屉
  leftdrawer: boolean;
  // 请求信号
  controller: AbortController | null;
  // 终止按钮状态
  stopStatus: boolean;
}>({
  collapse: false,
  asideWidth: "",
  chatValue: {
    question: "",
  },
  chatStatus: {
    btnDisabled: true,
    loading: false,
  },
  messages: [
    {
      isCode: false,
      isPreview: false,
      text: "请对我说点什么...",
      type: accountType.GPT,
      avatar: chaticon,
    },
    // {
    //   isCode: false,
    //   isPreview: false,
    //   // text: "确保逐步拼接显示： 使用 onmessage 时，可以逐步添加每个字符或段落到现有的消息内容中。你可以在后台设置每个消息的发送间隔或者根据需要逐步返回数据。另外，确保你在处理返回数据时不会把每个字符视作一个单独的消息。你可以合并接收到的内容并在一个较长的消息里展示：",
    //   text: "1+1等于几",
    //   type: accountType.USER,
    //   avatar: chaticon,
    // },
  ],
  leftdrawer: false,
  controller: null,
  stopStatus: true,
});
//  获取知识库数据
const getKnowledgeBases = async () => {
  try {
    const { data } = await KnowledgeApi.getAllKnowledgeData(); // 替换为真实接口
    knowledgeBases.value = data.knowledge_bases; // 假设接口返回的是一个数组
    // 默认选中第一个知识库
    if (knowledgeBases.value.length > 0) {
      selectedKnowledgeBase.value = knowledgeBases.value[0].id;
    }
  } catch (error) {
    console.error("获取知识库失败", error);
  }
};

onMounted(() => {
  getKnowledgeBases();
});
// 控制aside收缩或展开
const onFlod = () => {
  asideWidth.value = collapse.value ? "260px" : "0";
  collapse.value = !collapse.value;
};

// 确认清空对话内容
const confirmEvent = () => {
  console.log("confirm!");
  data.messages = [
    {
      isCode: false,
      isPreview: false,
      text: "请对我说点什么...",
      type: accountType.GPT,
      avatar: chaticon,
    },
  ];
};

// 点击按钮提问
const handleButtonClick = async () => {
  if (data.chatValue.question.trim() === "") {
    ElMessage.warning("请对我说点什...");
    return;
  }
  data.stopStatus = false;
  data.controller = new AbortController();

  try {
    data.chatStatus.btnDisabled = false;
    data.chatStatus.loading = true;

    // 处理按钮点击事件
    data.messages.push({
      isCode: false,
      isPreview: false,
      text: data.chatValue.question,
      type: accountType.USER,
      avatar: "",
    });
    let question = data.chatValue.question;
    data.chatValue.question = "";

    // 模拟 GPT 回复
    data.messages.push({
      isCode: false,
      isPreview: true,
      text: "",
      type: accountType.GPT,
      avatar: chaticon,
    });

    scrollToLastMessage(); // 聚焦到最新消息

    // 使用 fetchEventSource 替换原来的 API 请求
    await fetchEventSource("/api/ask", {
      method: "POST", // 根据你的需求选择 POST 或 GET
      headers: {
        "Content-Type": "application/json",
        // 其他可能需要的头信息
      },
      body: JSON.stringify({
        query: question,
        kb_id: selectedKnowledgeBase.value, // 这个值根据你的业务逻辑来设定
      }),
      signal: data.controller.signal,
      onopen(res) {
        if (res.ok) {
          console.log("Connection established");
        }
      },
      onmessage(event) {
        let message = event.data;
        // 拼接新消息
        if (
          data.messages.length > 0 &&
          data.messages[data.messages.length - 1].isPreview
        ) {
          data.messages[data.messages.length - 1].text += message; // 拼接新数据到最后一条消息
        } else {
          // 如果是新的消息，添加到消息列表
          data.messages.push({
            isCode: false,
            isPreview: false,
            text: message,
            type: accountType.GPT,
            avatar: chaticon,
          });
        }
        scrollToLastMessage();
      },

      onerror(err) {
        console.error("Error occurred:", err);
        replaceData(); // 错误时替换数据
      },
      onclose() {
        console.log("Connection closed");
        question = "";
      },
    });
  } catch (error) {
    replaceData();
  } finally {
    scrollToLastMessage(); // 聚焦到最新消息
    data.chatStatus.loading = false;
    data.stopStatus = true;
  }
};

// 聚焦到最新消息
const scrollToLastMessage = () => {
  nextTick(() => {
    lastMessage.value.scrollIntoView({ behavior: "smooth", block: "end" });
  });
};

// 替换gpt测试数据为真实数据
const replaceData = (newMessage?: string) => {
  const msgIndex = data.messages.findIndex((item) => item.isPreview === true);

  if (msgIndex !== -1 && newMessage) {
    // 如果有新的消息，拼接到现有消息中
    const existingMessage = data.messages[msgIndex].text;
    data.messages[msgIndex].text = existingMessage + newMessage; // 拼接消息
  } else {
    // 如果没有新的消息，使用错误提示
    const errorData = {
      isCode: false,
      isPreview: false,
      text: "Sorry, I am unable to process your Request at the moment.",
      type: accountType.GPT,
      avatar: chaticon,
    };
    data.messages.splice(msgIndex, 1, errorData); // 将 preview 的消息替换为错误提示
  }
};

// 人为终止请求
const cancelRequest = () => {
  if (data.controller) {
    data.controller.abort();
    data.controller = null;
  }
};

const debouncedConfirmEvent = debounce(handleButtonClick, 300);

const { collapse, asideWidth, chatValue, chatStatus, leftdrawer, stopStatus } =
  toRefs(data);

// 监听消息变化，确保每次有新消息时自动聚焦
onMounted(() => {
  scrollToLastMessage();
});

// 监听输入框数据变化,控制发送按钮状态
watch(
  () => data.chatValue.question,
  (value) => {
    if (value.trim() !== "") {
      data.chatStatus.btnDisabled = false;
    } else {
      data.chatStatus.btnDisabled = true;
    }
  }
);
</script>
<style lang="less" scoped>
.container_cover {
  width: 100%;
  height: 100vh;
  overflow: hidden;
  padding: 16px;
  // border: 1px solid #abc;
  .container_center {
    width: 100%;
    height: 100%;
    border: 1px solid #e5e7eb;
    box-shadow: 1px 1px 3px 2px rgba(0, 0, 0, 0.2);
    border-radius: 10px; /* 设置圆角为 10px */
    overflow: hidden;

    .el-aside {
      transition: width 0.3s; /* 宽度变化过渡效果 */
    }
    .container_right {
      position: relative;
      .icon_style {
        width: 20px;
        height: 20px;
        border-radius: 10px;
        border: 1px solid #abc;
        position: absolute;
        left: -10px;
        top: 50%;
        z-index: 1;
        background-color: #fff;
      }
      .icon_style:hover {
        border: 2px solid #abc;
      }
      .chatview {
        width: 100%;
        height: calc(100% - 72px);
        overflow-y: auto;
        position: absolute;
        left: 0;
        top: 0;
        padding: 16px;
        // border: 1px solid red;
        display: flex;
        flex-direction: column;

        .gpt-message {
          display: flex;
          justify-content: flex-start;
          align-items: center;
          padding: 6px;
          // background-color: #abc;
          margin-bottom: 10px;
          margin-right: 80px;
          // border: 1px solid red;
          .gpt_head {
            display: flex;
            align-items: center;
            margin-bottom: 10px;
          }
        }

        .user-message {
          display: inline-block; /* 改为 inline-block 来让宽度自适应内容 */
          padding: 10px;
          font-size: 16px;
          line-height: 28px;
          color: #262626;
          background-color: #eff6ff;
          border-radius: 14px;
          margin-bottom: 10px;
          box-sizing: border-box;
          white-space: pre-wrap; /* 允许文本换行 */
          word-break: break-word; /* 确保文本不会溢出 */
          position: relative;
          margin-left: auto;
          margin-right: 20px;
        }

        .user_head {
          display: flex;
          align-items: center;
          margin-bottom: 10px;
        }

        .message-text {
          margin-left: 10px;
          margin-right: 10px;
          font-size: 16px;
          line-height: 28px;
          color: #262626;
          box-sizing: border-box;
          white-space: pre-wrap;
          word-break: break-word;
        }
        /* 新增的代码消息样式 */
        .code-message {
          background-color: #000;
          color: #fff;
          padding: 10px;
          border-radius: 5px;
          white-space: pre-wrap;
        }
      }
      .sengChat {
        width: 100%;
        height: 72px;
        position: absolute;
        left: 0;
        bottom: 0;
        padding: 16px;
        // border: 1px solid red;
        display: flex;
        align-items: center;
        justify-content: space-around;
        box-sizing: border-box;
        .delete_icon {
          width: 40px;
          height: 36px;
          cursor: pointer;
          line-height: 36px;
        }
        .delete_icon:hover {
          background-color: #e5e7eb;
          border-radius: 20px;
          box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* 设置阴影 */
        }
        .kb-label{
          width: 64px;
          font-size: 14px;
          color: #606266;
        }
        .kb-select{
          width: 20%;
        }
        .el-input {
          height: 36px;
          margin: 0 12px;
        }
        .el-button {
          height: 36px;
        }
      }
    }
  }
}
</style>
